#include "Layer_List.h"


class Layer_List_Cleaner
{
public:
    ~Layer_List_Cleaner() {
        Layer_List::destroy();
    }
} Layer_List_cleaner_instance;

Layer_List* Layer_List::instance = NULL;

Layer_List::Layer_List() :
    m_layerIndexCounter(0),
    m_layerCount(0)
{

    addLayer();
    if (Debug::test(DEBUG_CREATE_DELETE)) {
        cout << "Layer_List created" << endl;
    }
}

int Layer_List::addLayer()
{
    lock();
    Layer *player = new Layer(m_layerIndexCounter, 0);
    if(Debug::test(DEBUG_INFO)) {
        cout << "New layer " << m_layerIndexCounter << " added" << endl;
    }
    m_layers.push_back(player);
    m_layerIndexCounter++;
    m_layerCount++;
    unlock();
    return m_layerIndexCounter - 1;
}

Layer_List::~Layer_List() {
    clear();
    if (Debug::test(DEBUG_CREATE_DELETE)) {
        cout << "Layer_List deleted" << endl;
    }
}

Layer_List* Layer_List::get_instance() {
    if(!instance) {
        instance = new Layer_List();
    }
    return instance;
}

void Layer_List::destroy() {
    if(instance) {
        delete(instance);
        instance = NULL;
        if(Debug::test(DEBUG_CREATE_DELETE)) {
            cout << "Layer_List destroyed" << endl;
        }
    }
}

Layer &Layer_List::operator[] (uint index) {
    m_mutex.lock();
    list<Layer *> :: iterator i;
    bool found = false;
    for(i = m_layers.begin(); i != m_layers.end(); i++) {
        if((*i)->getLayerId() == index) {
            found = true;
            break;
        }
        if (Debug::test(DEBUG_INFO)) {
            cout << "Searching layer " << (*i)->getLayerId() << " != " << index << endl;
        }
    }
    m_mutex.unlock();
    if (!found) {
        throw runtime_error("Layer_List::operator[] - Couldn't map index to Layer. Index: " + formatInt(index,4));
    }
    return **i;
}

void Layer_List::setVisible (uint index, bool visible) {
    m_mutex.lock();
    list<Layer *> :: iterator i;
    for (i = m_layers.begin(); i != m_layers.end(); i++) {
        if ((*i)->getLayerId() == index) {
            (*i)->setVisible(visible);
            break;
        }
    }
    m_mutex.unlock();
}

void Layer_List::clear() {
    lock();
    list<Layer *>::iterator itr;
    for(itr = m_layers.begin(); itr != m_layers.end(); itr++) {
        (*itr)->clear();
        delete *itr;
        *itr = NULL;
    }
    m_layers.clear();
    m_layerIndexCounter = 0;
    m_layerCount = 0;
    unlock();
}

int Layer_List::removeLayer(uint layerid) {
    int newActiveLayerId = INVALID_LAYER_ID;
    lock();
    list<Layer *>::iterator itr;
    for(itr = m_layers.begin(); itr != m_layers.end(); itr++) {
        if ((*itr)->getLayerId() == layerid) {
            (*itr)->clear();
            delete *itr;
            *itr = NULL;
            m_layers.erase(itr);
            m_layerCount--;
            break;
        }
    }
    itr = m_layers.begin();
    if (itr != m_layers.end()) {
        newActiveLayerId = (*itr)->getLayerId();
    }
    unlock();
    if (Debug::test(DEBUG_ADD_REMOVE)) {
        cout << "Removed Layer " << layerid << " " << newActiveLayerId << " is the new ActiveLayerIndex" << endl;
    }
    return newActiveLayerId;
}
